图(邻接矩阵)的深度、广度优先遍历

本文介绍了如何使用C++实现图的深度优先遍历(DFS)和广度优先遍历(BFS),通过邻接矩阵存储图数据,并提供了创建图、初始化队列、判断队列是否为空以及入队、出队等辅助函数。
摘要由CSDN通过智能技术生成
/*******************************************************************************
*																			   *
*					图(邻接矩阵存储)的深度优先和广度优先					   *
*																			   *
*******************************************************************************/
#include<iostream>
#define MaxVertexNum  30
using namespace std;
bool visited[MaxVertexNum];

typedef int VertexType;
typedef int Edgetype;
typedef struct{
	VertexType vertexs[MaxVertexNum];
	Edgetype arcs[MaxVertexNum][MaxVertexNum];
	int vertexNum,edgeNum;
}MGraph;

typedef int DataType;
typedef struct{				/*队列*/
	DataType data[MaxVertexNum];//数据域
	int front,rear;//队头和队尾指针
}SeqQueue,* PSeqQueue;

void Create_MGraph(MGraph * G);				/*创建图*/
void DFStraverse(MGraph * G);				/*深度优先*/
void DFS(MGraph * G,int v);					/*深度优先搜索算法*/
void BFStraverse(MGraph * G);				/*广度优先*/
void BFS(MGraph * G,int v);					/*广度优先搜索算法*/

PSeqQueue Init_SeqQueue(void);				/*循环队列初始化*/
int Empty_SeqQueue(PSeqQueue Q);			/*判断队空*/
void In_SeqQueue(PSeqQueue Q,DataType x);	/*入队*/
void Out_SeqQueue(PSeqQueue Q,DataType * y);/*出队*/

int main(){
	cout<<"创建图:";
	MGraph * G=(MGraph *)malloc(sizeof(MGraph));
	Create_MGraph(G);

	cout<<"\n深度优先遍历(图):";
	DFStraverse(G);
	cout<<"\b\b";
	cout<<"\n广度优先遍历(图):";
	BFStraverse(G);
	cout<<"\b\b";

	return 0;
}

/*创建图*/
void Create_MGraph(MGraph * G){
	int i,j,k;

	cout<<"请输入图的顶点数和边数:";
	cin>>G->vertexNum>>G->edgeNum;
	cout<<"输入"<<G->vertexNum<<"个顶点的表示形式:";
	for(i=0;i<G->vertexNum;i++)
		cin>>G->vertexs[i];		/*顶点是字符还是数字*/

	for(i=0;i<G->vertexNum;i++){
		for(j=0;j<G->vertexNum;j++){
			G->arcs[i][j]=0;
		}
	}
	VertexType v1,v2;
	for(k=0;k<G->edgeNum;k++){
		cout<<"读入边(Vi,Vj)起点和终点对应的序号:";
		cin>>v1>>v2;
		for(i=0;v1!=G->vertexs[i];i++);
		for(j=0;v2!=G->vertexs[j];j++);
		G->arcs[i][j]=1;
		G->arcs[j][i]=1;
	}
}

/*深度优先搜索算法*/
void DFS(MGraph * G,int v){
	cout<<G->vertexs[v]<<"->";
	visited[v]=true;/*访问第v个顶点,并把访问标志置true*/

	for(int w=0;w<G->vertexNum;w++){
		if(G->arcs[v][w]==1 && !visited[w])/*对v尚未访问的邻接顶点w入队列Q*/
			DFS(G,w);
	}
}

/*深度优先*/
void DFStraverse(MGraph * G){
	int v;
	for(v=0;v<G->vertexNum;v++)
		visited[v]=false;
	for(v=0;v<G->vertexNum;v++){
		if(!visited[v])
			DFS(G,v);
	}
}

void BFStraverse(MGraph * G){
	int v;
	for(v=0;v<G->vertexNum;v++)
		visited[v]=false;
	for(v=0;v<G->vertexNum;v++){
		if(!visited[v])
			BFS(G,v);
	}
}

void BFS(MGraph * G,int v){
	int u,w;

	cout<<G->vertexs[v]<<"->";
	visited[v]=true;/*访问第v个顶点,并把访问标志置true*/
	PSeqQueue Q=Init_SeqQueue();
	In_SeqQueue(Q,v);

	while(!Empty_SeqQueue(Q)){
		Out_SeqQueue(Q,&u);
		for(w=0;w<G->vertexNum;w++){
			if(G->arcs[u][w]==1 && !visited[w]){/*对v尚未访问的邻接顶点w入队列Q*/
				cout<<G->vertexs[w]<<"->";
				visited[w]=true;
				In_SeqQueue(Q,w);
			}
		}
	}
}

/*循环队列初始化*/
PSeqQueue Init_SeqQueue(void){
	PSeqQueue Q;
	Q=(PSeqQueue)malloc(sizeof(SeqQueue));
	if(Q){
		Q->front=0;
		Q->rear=0;
	}
	return Q;
}

/*判断队空*/
int Empty_SeqQueue(PSeqQueue Q){
	if(Q && Q->front==Q->rear)
		return 1;
	else 
		return 0;
}

/*入队*/
void In_SeqQueue(PSeqQueue Q,DataType x){
	if(Q->front == (Q->rear+1)%MaxVertexNum){
		cout<<"队满不能入队!";
		return;
	}else{
		Q->rear=(Q->rear+1)%MaxVertexNum;
		Q->data[Q->rear]=x;
	}
}

/*出队*/
void Out_SeqQueue(PSeqQueue Q,DataType * y){
	if(Empty_SeqQueue(Q)){
		cout<<"队空不能出队!";
		return;
	}else{
		Q->front=(Q->front+1)%MaxVertexNum;
		* y=Q->data[Q->front];
	}
}

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 邻接矩阵深度优先遍历广度优先遍历的两种遍历方式。 深度优先遍历是从起点开始,沿着一条路径一直走到底,直到不能再走为止,然后返回上一个节点,继续走其他路径,直到所有节点都被访问过为止。在邻接矩阵中,可以使用递归或栈来实现深度优先遍历广度优先遍历是从起点开始,先访问起点的所有邻居节点,然后依次访问它们的邻居节点,直到所有节点都被访问过为止。在邻接矩阵中,可以使用队列来实现广度优先遍历。 ### 回答2: 邻接矩阵的一种常见表示方法,其中通过二维数组来表示的节点之间的关系。在邻接矩阵中,每个节点(或者说顶点)的行代表其所在的节点,而列则代表其与其他节点之间是否存在连边。如果该节点与另一个节点存在连边,则邻接矩阵中该行、该列的交叉处值为1,反之,如果不存在连边,则该交叉处值为0。基于邻接矩阵,我们可以进行深度优先遍历广度优先遍历深度优先遍历(DFS)是一种对进行遍历的方式,遵循“先访问子节点再访问兄弟节点”的原则。具体来说,该算法从某个节点开始遍历,访问其第一个未访问的子节点,对该子节点执行DFS遍历,直到到达某个叶子节点为止。然后回溯,访问该节点的下一个未访问的子节点,继续执行DFS遍历,直到所有子节点都被遍历完毕。DFS遍历过的节点,会在遍历结束后形成一个连通块。对于邻接矩阵,我们可以通过递归实现DFS遍历: ``` void dfs(int u) { visited[u] = true; // 标记该节点已被访问 for(int v = 0; v < n; v++) { // 枚举该节点的所有邻接点 if(!visited[v] && matrix[u][v]) { // 如果该邻接点未被访问且与该节点相邻 dfs(v); // 则访问该邻接点 } } } ``` 广度优先遍历(BFS)也是一种对进行遍历的方式,遵循“先访问距离起点最近的节点”的原则。具体来说,该算法从某个节点开始遍历,将其入队,然后访问其所有的邻接点,并将其邻接点入队。然后从队首取出下一个节点,重复上述步骤,直到所有的节点都被遍历完毕。BFS遍历过的节点,会在遍历结束后形成一棵广度优先搜索树。对于邻接矩阵,我们可以通过队列实现BFS遍历: ``` void bfs(int u) { queue<int> q; q.push(u); // 将起点入队 visited[u] = true; // 标记该节点已被访问 while(!q.empty()) { // 如果队列非空 int u = q.front(); // 取出队首节点 q.pop(); for(int v = 0; v < n; v++) { // 枚举该节点的所有邻接点 if(!visited[v] && matrix[u][v]) { // 如果该邻接点未被访问且与该节点相邻 visited[v] = true; // 标记该节点已被访问 q.push(v); // 将该邻接点入队 } } } } ``` 总之,邻接矩阵的一种常见表示方法,DFS和BFS遍历是对进行遍历的常用算法,它们可以通过递归和队列实现。掌握邻接矩阵的DFS和BFS遍历,可以更好地理解的相关算法数据结构,也有助于解决各种实际问题。 ### 回答3: 邻接矩阵的一种常见存储方式。深度优先遍历(DFS)和广度优先遍历(BFS)是针对进行的两种遍历方式。下面将详细解释邻接矩阵的DFS和BFS的过程和实现方法。 邻接矩阵的DFS遍历深度优先遍历通常使用递归的方式来实现。具体的深度优先遍历邻接矩阵的过程如下: 1. 从一个顶点开始进行遍历; 2. 访问该顶点,并标记该顶点为已访问; 3. 从该顶点出发,找到一个未被访问过的相邻顶点,标记该顶点为已访问,然后递归到该顶点继续递归遍历; 4. 如果该顶点没有相邻未访问过的顶点,则回溯到最近一个有未访问过相邻顶点的顶点,然后继续递归遍历其它相邻顶点。 邻接矩阵的BFS遍历广度优先遍历则使用队列的方式来实现。具体的广度优先遍历邻接矩阵的过程如下: 1. 从一个顶点开始进行遍历; 2. 将该顶点加入队列中,并标记该顶点为已访问; 3. 从队列中取出一个未被访问过的顶点,访问该顶点,并将其未被访问过的相邻顶点加入队列中,并标记这些顶点为已访问; 4. 重复步骤3直到队列为空。 邻接矩阵的DFS和BFS的时间复杂度都为O(V^2),其中V为顶点数。DFS相对BFS来说,更适用于查找路径的问题,快速查找到节点之间的路径信息;BFS适用于确定最短路径和寻找最近解问题。 总而言之,邻接矩阵是一种常见的的存储方式,DFS和BFS是对的两种常用遍历方式。它们各自有适用性,要根据具体情况进行选择。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值